import { Ionicons } from "@expo/vector-icons";
import {
  BottomSheetBackdrop,
  type BottomSheetBackdropProps,
  BottomSheetModal,
  BottomSheetScrollView,
} from "@gorhom/bottom-sheet";
import type {
  MediaSourceInfo,
  MediaStream,
} from "@jellyfin/sdk/lib/generated-client";
import type React from "react";
import { useMemo, useRef } from "react";
import { useTranslation } from "react-i18next";
import { TouchableOpacity, View } from "react-native";
import { formatBitrate } from "@/utils/bitrate";
import { Badge } from "./Badge";
import { Text } from "./common/Text";

interface Props {
  source?: MediaSourceInfo;
}

export const ItemTechnicalDetails: React.FC<Props> = ({ source }) => {
  const bottomSheetModalRef = useRef<BottomSheetModal>(null);
  const { t } = useTranslation();

  return (
    <View className='px-4 mt-2 mb-4'>
      <Text className='text-lg font-bold mb-4'>{t("item_card.video")}</Text>
      <TouchableOpacity onPress={() => bottomSheetModalRef.current?.present()}>
        <View className='flex flex-row space-x-2'>
          <VideoStreamInfo source={source} />
        </View>
        <Text className='text-purple-600'>{t("item_card.more_details")}</Text>
      </TouchableOpacity>
      <BottomSheetModal
        ref={bottomSheetModalRef}
        snapPoints={["80%"]}
        handleIndicatorStyle={{
          backgroundColor: "white",
        }}
        backgroundStyle={{
          backgroundColor: "#171717",
        }}
        backdropComponent={(props: BottomSheetBackdropProps) => (
          <BottomSheetBackdrop
            {...props}
            disappearsOnIndex={-1}
            appearsOnIndex={0}
          />
        )}
      >
        <BottomSheetScrollView>
          <View className='flex flex-col space-y-2 p-4 mb-4'>
            <View>
              <Text className='text-lg font-bold mb-4'>
                {t("item_card.video")}
              </Text>
              <View className='flex flex-row space-x-2'>
                <VideoStreamInfo source={source} />
              </View>
            </View>

            <View>
              <Text className='text-lg font-bold mb-2'>
                {t("item_card.audio")}
              </Text>
              <AudioStreamInfo
                audioStreams={
                  source?.MediaStreams?.filter(
                    (stream) => stream.Type === "Audio",
                  ) || []
                }
              />
            </View>

            <View>
              <Text className='text-lg font-bold mb-2'>
                {t("item_card.subtitles")}
              </Text>
              <SubtitleStreamInfo
                subtitleStreams={
                  source?.MediaStreams?.filter(
                    (stream) => stream.Type === "Subtitle",
                  ) || []
                }
              />
            </View>
          </View>
        </BottomSheetScrollView>
      </BottomSheetModal>
    </View>
  );
};

const SubtitleStreamInfo = ({
  subtitleStreams,
}: {
  subtitleStreams: MediaStream[];
}) => {
  return (
    <View className='flex flex-col'>
      {subtitleStreams.map((stream, _index) => (
        <View key={stream.Index} className='flex flex-col'>
          <Text className='text-xs mb-3 text-neutral-400'>
            {stream.DisplayTitle}
          </Text>
          <View className='flex flex-row flex-wrap gap-2'>
            <Badge
              variant='gray'
              iconLeft={
                <Ionicons name='language-outline' size={16} color='white' />
              }
              text={stream.Language}
            />
            <Badge
              variant='gray'
              text={stream.Codec}
              iconLeft={
                <Ionicons name='layers-outline' size={16} color='white' />
              }
            />
          </View>
        </View>
      ))}
    </View>
  );
};

const AudioStreamInfo = ({ audioStreams }: { audioStreams: MediaStream[] }) => {
  return (
    <View className='flex flex-col'>
      {audioStreams.map((audioStreams, index) => (
        <View key={index} className='flex flex-col'>
          <Text className='mb-3 text-neutral-400 text-xs'>
            {audioStreams.DisplayTitle}
          </Text>
          <View className='flex-row flex-wrap gap-2'>
            <Badge
              variant='gray'
              iconLeft={
                <Ionicons name='language-outline' size={16} color='white' />
              }
              text={audioStreams.Language}
            />
            <Badge
              variant='gray'
              iconLeft={
                <Ionicons
                  name='musical-notes-outline'
                  size={16}
                  color='white'
                />
              }
              text={audioStreams.Codec}
            />
            <Badge
              variant='gray'
              iconLeft={<Ionicons name='mic-outline' size={16} color='white' />}
              text={audioStreams.ChannelLayout}
            />
            <Badge
              variant='gray'
              iconLeft={
                <Ionicons name='speedometer-outline' size={16} color='white' />
              }
              text={formatBitrate(audioStreams.BitRate)}
            />
          </View>
        </View>
      ))}
    </View>
  );
};

const VideoStreamInfo = ({ source }: { source?: MediaSourceInfo }) => {
  const videoStream = useMemo(() => {
    return source?.MediaStreams?.find((stream) => stream.Type === "Video") as
      | MediaStream
      | undefined;
  }, [source?.MediaStreams]);

  if (!source || !videoStream) return null;

  return (
    <View className='flex-row flex-wrap gap-2'>
      <Badge
        variant='gray'
        iconLeft={<Ionicons name='film-outline' size={16} color='white' />}
        text={formatFileSize(source.Size)}
      />
      <Badge
        variant='gray'
        iconLeft={<Ionicons name='film-outline' size={16} color='white' />}
        text={`${videoStream.Width}x${videoStream.Height}`}
      />
      <Badge
        variant='gray'
        iconLeft={
          <Ionicons name='color-palette-outline' size={16} color='white' />
        }
        text={videoStream.VideoRange}
      />
      <Badge
        variant='gray'
        iconLeft={
          <Ionicons name='code-working-outline' size={16} color='white' />
        }
        text={videoStream.Codec}
      />
      <Badge
        variant='gray'
        iconLeft={
          <Ionicons name='speedometer-outline' size={16} color='white' />
        }
        text={formatBitrate(videoStream.BitRate)}
      />
      <Badge
        variant='gray'
        iconLeft={<Ionicons name='play-outline' size={16} color='white' />}
        text={
          videoStream.AverageFrameRate != null
            ? `${videoStream.AverageFrameRate.toFixed(0)} fps`
            : ""
        }
      />
    </View>
  );
};

const formatFileSize = (bytes?: number | null) => {
  if (!bytes) return "N/A";

  const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
  if (bytes === 0) return "0 Byte";
  const i = Number.parseInt(
    Math.floor(Math.log(bytes) / Math.log(1024)).toString(),
    10,
  );
  return `${Math.round((bytes / 1024 ** i) * 100) / 100} ${sizes[i]}`;
};
